package com.wandian.texas.net;

import com.wandian.util.Log;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;
import java.util.Set;

/**
 * @date : 2012-9-25, 16:07:58
 * @author: long
 * @email :108232706
 * @qq.com
 * @description: SessionManager类
 */
public class NioManager implements ISessionManager {

    private static Selector selector = null;
    private static NioManager instance = null;
    private ThreadLocal<StringBuffer> stringLocal = new ThreadLocal<StringBuffer>();

    private NioManager() throws IOException {
    }

    public boolean start(int port, int maxCount) throws IOException {
        selector = Selector.open(); //静态方法 实例化selector
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.configureBlocking(true);  //设置为非阻塞方式,如果为true 那么就为传统的阻塞方式
        serverChannel.socket().bind(new InetSocketAddress(port)); //绑定IP 及 端口
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);//注册 OP_ACCEPT事件

        int keyAdded = 0;
        while ((keyAdded = selector.select()) > 0) {
            Set<SelectionKey> keySets = selector.selectedKeys();
            Iterator iter = keySets.iterator();
            while (iter.hasNext()) {
                SelectionKey key = (SelectionKey) iter.next();
                iter.remove();
                actionHandler(key);
            }
        }
        return true;
    }

    public void actionHandler(SelectionKey key) throws IOException {
        if (key.isAcceptable()) {
            ServerSocketChannel serverChannel = (ServerSocketChannel) key
                    .channel();
            SocketChannel socketChannel = serverChannel.accept();
            socketChannel.configureBlocking(false);
            socketChannel.register(selector, SelectionKey.OP_READ);
        } else if (key.isReadable()) {
            ByteBuffer buffer = ByteBuffer.allocate(16);
            SocketChannel socketChannel = (SocketChannel) key.channel();
            socketChannel.read(buffer);
            buffer.flip();
            String temp = decode(buffer);
            StringBuffer strBuffer = stringLocal.get();
            if (strBuffer == null) {
                strBuffer = new StringBuffer();
            }
            strBuffer.append(temp);
            if (temp.equals("\r\n")) {
                System.out.println(strBuffer.toString());
                strBuffer = null;
            }
            stringLocal.set(strBuffer);
        }
    }

    public String decode(ByteBuffer buffer) {
        Charset charset = null;
        CharsetDecoder decoder = null;
        CharBuffer charBuffer = null;
        try {
            charset = Charset.forName("UTF-8");
            decoder = charset.newDecoder();
            charBuffer = decoder.decode(buffer);
            return charBuffer.toString();
        } catch (Exception ex) {
            ex.printStackTrace();
            return "";
        }
    }

    public synchronized static NioManager getInstance() throws IOException {
        if (instance == null) {
            instance = new NioManager();
        }
        return instance;
    }

    public void acceptProcessor() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean stop() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
